using Fiddler;
using System;
using System.Text;

namespace TangCaptureTraffic.Services
{
    /// <summary>
    /// 会话格式化服务实现类，提供网络会话对象的格式化和处理功能
    /// </summary>
    public class SessionFormattingService : ISessionFormattingService
    {
        private readonly IDataFormattingService _dataFormattingService;

        public SessionFormattingService(IDataFormattingService dataFormattingService)
        {
            _dataFormattingService = dataFormattingService ?? throw new ArgumentNullException(nameof(dataFormattingService));
        }

        /// <summary>
        /// 将Fiddler会话对象转换为详细的可读字符串格式
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话详细信息的格式化字符串，如果会话为null则返回null</returns>
        public string FormatSessionDetails(Session session)
        {
            if (session == null) return null;

            var sb = new StringBuilder();

            // 添加会话基本信息
            AppendSessionBasicInfo(sb, session);
            sb.AppendLine();

            // 添加请求头信息
            sb.AppendLine(FormatRequestHeaders(session));
            sb.AppendLine();

            // 添加请求体内容
            var requestBody = FormatRequestBody(session);
            if (!string.IsNullOrEmpty(requestBody))
            {
                sb.AppendLine(requestBody);
                sb.AppendLine();
            }

            // 添加响应头信息
            sb.AppendLine(FormatResponseHeaders(session));
            sb.AppendLine();

            // 添加响应体内容
            var responseBody = FormatResponseBody(session);
            if (!string.IsNullOrEmpty(responseBody))
            {
                sb.AppendLine(responseBody);
            }

            return sb.ToString();
        }

        /// <summary>
        /// 获取会话的请求信息文本，包括请求头和请求体
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话请求详细信息的格式化字符串，如果会话为null则返回null</returns>
        public string FormatRequestText(Session session)
        {
            if (session == null) return null;

            var sb = new StringBuilder();

            // 添加会话基本信息
            AppendSessionBasicInfo(sb, session);
            sb.AppendLine();

            // 添加请求头信息
            sb.AppendLine(FormatRequestHeaders(session));
            sb.AppendLine();

            // 添加请求体内容
            var requestBody = FormatRequestBody(session);
            if (!string.IsNullOrEmpty(requestBody))
            {
                sb.AppendLine(requestBody);
            }

            return sb.ToString();
        }

        /// <summary>
        /// 获取会话的响应信息文本，包括响应头和响应体
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话响应详细信息的格式化字符串，如果会话为null则返回null</returns>
        public string FormatResponseText(Session session)
        {
            if (session == null) return null;

            var sb = new StringBuilder();

            // 添加响应头信息
            sb.AppendLine(FormatResponseHeaders(session));
            sb.AppendLine();

            // 添加响应体内容
            var responseBody = FormatResponseBody(session);
            if (!string.IsNullOrEmpty(responseBody))
            {
                sb.AppendLine(responseBody);
            }

            return sb.ToString();
        }

        /// <summary>
        /// 格式化请求头
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <returns>格式化的请求头字符串</returns>
        public string FormatRequestHeaders(Session session)
        {
            if (session == null) return string.Empty;

            var sb = new StringBuilder();
            sb.AppendLine("=== 请求头 ===");
            
            foreach (var header in session.RequestHeaders)
            {
                sb.AppendLine($"{header.Name}: {header.Value}");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 格式化响应头
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <returns>格式化的响应头字符串</returns>
        public string FormatResponseHeaders(Session session)
        {
            if (session == null) return string.Empty;

            var sb = new StringBuilder();
            sb.AppendLine("=== 响应头 ===");
            
            foreach (var header in session.ResponseHeaders)
            {
                sb.AppendLine($"{header.Name}: {header.Value}");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 格式化请求体
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="maxLength">最大长度限制</param>
        /// <returns>格式化的请求体字符串</returns>
        public string FormatRequestBody(Session session, int maxLength = 5000)
        {
            if (session == null) return string.Empty;
            
            // 检查请求体大小，如果超过阈值，先返回提示信息
            if (session.RequestBody != null && session.RequestBody.Length > 500000) // 500KB
            {
                var sb = new StringBuilder();
                sb.AppendLine("=== 请求体 ===");
                sb.AppendLine($"[大型请求体，大小: {_dataFormattingService.FormatFileSize(session.RequestBody.Length)}]\n");
                sb.AppendLine("请求体过大，正在加载中...");
                
                // 异步加载完整内容
                Task.Run(() => {
                    try {
                        return session.GetRequestBodyAsString();
                    } catch {
                        return "[无法加载请求体内容]";
                    }
                });
                
                return sb.ToString();
            }

            // 对于正常大小的请求体，直接处理
            try
            {
                var requestBody = session.GetRequestBodyAsString();
                if (string.IsNullOrEmpty(requestBody)) return string.Empty;

                var sb = new StringBuilder();
                sb.AppendLine("=== 请求体 ===");
                
                if (requestBody.Length > maxLength)
                {
                    sb.AppendLine(requestBody.Substring(0, maxLength));
                    sb.AppendLine($"\n... (请求体过长，已截断，完整长度: {requestBody.Length} 字符)");
                }
                else
                {
                    sb.AppendLine(requestBody);
                }

                return sb.ToString();
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();
                sb.AppendLine("=== 请求体 ===");
                sb.AppendLine($"[加载请求体时出错: {ex.Message}]");
                return sb.ToString();
            }
        }

        /// <summary>
        /// 格式化响应体
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="maxLength">最大长度限制</param>
        /// <returns>格式化的响应体字符串</returns>
        public string FormatResponseBody(Session session, int maxLength = 5000)
        {
            if (session == null) return string.Empty;
            
            // 检查响应体大小，如果超过阈值，先返回提示信息
            if (session.ResponseBody != null && session.ResponseBody.Length > 1000000) // 1MB
            {
                var sb = new StringBuilder();
                sb.AppendLine("=== 响应体 ===");
                sb.AppendLine($"[大型响应体，大小: {_dataFormattingService.FormatFileSize(session.ResponseBody.Length)}]\n");
                sb.AppendLine("响应体过大，正在加载中...");
                sb.AppendLine("提示：大型响应可能需要较长时间加载，请耐心等待。");
                
                // 异步加载完整内容
                Task.Run(() => {
                    try {
                        return session.GetResponseBodyAsString();
                    } catch {
                        return "[无法加载响应体内容]";
                    }
                });
                
                return sb.ToString();
            }

            // 对于正常大小的响应体，直接处理
            try
            {
                var responseBody = session.GetResponseBodyAsString();
                if (string.IsNullOrEmpty(responseBody)) return string.Empty;

                var sb = new StringBuilder();
                sb.AppendLine("=== 响应体 ===");
                
                if (responseBody.Length > maxLength)
                {
                    sb.AppendLine(responseBody.Substring(0, maxLength));
                    sb.AppendLine($"\n... (响应体过长，已截断，完整长度: {responseBody.Length} 字符)");
                }
                else
                {
                    sb.AppendLine(responseBody);
                }

                return sb.ToString();
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();
                sb.AppendLine("=== 响应体 ===");
                sb.AppendLine($"[加载响应体时出错: {ex.Message}]");
                return sb.ToString();
            }
        }

        /// <summary>
        /// 添加会话基本信息
        /// </summary>
        /// <param name="sb">字符串构建器</param>
        /// <param name="session">会话对象</param>
        private void AppendSessionBasicInfo(StringBuilder sb, Session session)
        {
            sb.AppendLine($"=== 会话 #{session["flagname"]} ===");
            sb.AppendLine($"请求方法: {session.RequestMethod}");
            sb.AppendLine($"请求URL: {session.fullUrl}");
            sb.AppendLine($"主机: {session.hostname}");
            sb.AppendLine($"状态码: {_dataFormattingService.FormatStatusCode(session.responseCode)}");

            // 添加响应信息
            var contentType = session.ResponseHeaders["Content-Type"];
            if (!string.IsNullOrEmpty(contentType))
            {
                sb.AppendLine($"内容类型: {_dataFormattingService.SimplifyContentType(contentType)}");
            }

            if (session.ResponseBody != null)
            {
                sb.AppendLine($"响应大小: {_dataFormattingService.FormatFileSize(session.ResponseBody.Length)}");
            }
        }

        /// <summary>
        /// 将会话请求转换为cURL命令
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <returns>cURL命令字符串</returns>
        public string FormatRequestAsCurl(Session session)
        {
            if (session == null) return string.Empty;

            var sb = new StringBuilder();
            sb.Append($"curl -X {session.RequestMethod} ");

            // 添加请求头
            foreach (var header in session.RequestHeaders)
            {
                // 跳过Host头，因为URL中已包含
                if (header.Name.ToLower() == "host") continue;
                
                // 转义引号
                string escapedValue = header.Value.Replace("\"", "\\\"");
                sb.Append($"-H \"{header.Name}: {escapedValue}\" ");
            }

            // 添加请求体
            if (session.RequestBody != null && session.RequestBody.Length > 0)
            {
                string bodyStr = session.GetRequestBodyAsString();
                if (!string.IsNullOrEmpty(bodyStr))
                {
                    // 转义引号
                    bodyStr = bodyStr.Replace("\"", "\\\"");
                    sb.Append($"-d \"{bodyStr}\" ");
                }
            }

            // 添加URL（放在最后）
            sb.Append($"\"{session.fullUrl}\"");

            return sb.ToString();
        }
    }
}